package com.zg.autoflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zg.autoflow.dao.mapper.AutoFlowBusinessMapper;
import com.zg.autoflow.req.*;
import com.zg.autoflow.service.AutoflowExtStepConfigService;
import com.zg.autoflow.vo.AutoflowExtStepConfigFindVo;
import com.zg.common.core.dao.autoflow.dao.*;
import com.zg.common.core.dao.autoflow.entity.*;
import com.zg.common.core.dao.autoform.DiyForm;
import com.zg.common.core.dao.autoform.DiyFormDao;
import com.zg.common.core.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
* @author zg
*/
@Service
@RequiredArgsConstructor
public class AutoflowExtStepConfigServiceImpl implements AutoflowExtStepConfigService {

    private final AutoflowExtStepConfigDao autoflowExtStepConfigDao;
    private final AutoflowExtStepConfigPrevDao autoflowExtStepConfigPrevDao;
    private final AutoflowStepDao autoflowStepDao;
    private final AutoflowMainDao autoflowMainDao;
    private final AutoflowStepFormDao autoflowStepFormDao;
    private final DiyFormDao diyFormDao;
    private final AutoFlowBusinessMapper autoFlowBusinessMapper;


    @Override
    public AutoflowExtStepConfigFindVo findStepInfo(AutoflowExtStepConfigFindReq req) {
        LambdaQueryWrapper<AutoflowStep> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AutoflowStep::getFlowId, req.getFlowId());
        queryWrapper.eq(AutoflowStep::getStepNo, req.getStepNo());
        AutoflowStep step = autoflowStepDao.getOne(queryWrapper);
        if (step == null) {
           BusinessException.happen("环节不存在");
        }
        AutoflowExtStepConfigFindVo autoflowExtStepConfigFindVo = new AutoflowExtStepConfigFindVo();
        //查询环节配置
        LambdaQueryWrapper<AutoflowExtStepConfig> configQueryWrapper = new LambdaQueryWrapper<>();
        configQueryWrapper.eq(AutoflowExtStepConfig::getFlowCode, req.getFlowCode());
        configQueryWrapper.eq(AutoflowExtStepConfig::getStepNo, req.getStepNo());
        AutoflowExtStepConfig config = autoflowExtStepConfigDao.getOne(configQueryWrapper);
        List<AutoflowExtStepConfigPrev> prevConfigList = new ArrayList<>();
        if (config != null) {
            prevConfigList = autoflowExtStepConfigPrevDao.list(new QueryWrapper<AutoflowExtStepConfigPrev>().lambda().eq(AutoflowExtStepConfigPrev::getConfigId, config.getId()));
        }
        autoflowExtStepConfigFindVo.setExtStepConfig(config);
        autoflowExtStepConfigFindVo.setPrevsList(prevConfigList);
        return autoflowExtStepConfigFindVo ;
    }

    @Override
    public List<DiyForm> listFlowForm(AutoflowMainCodeReq req) {
        AutoflowMain autoflowMain = autoflowMainDao.getOne(new LambdaQueryWrapper<AutoflowMain>().eq(AutoflowMain::getCode, req.getFlowCode()));
        List<AutoflowStep> list = autoflowStepDao.list(new LambdaQueryWrapper<AutoflowStep>().eq(AutoflowStep::getFlowId, autoflowMain.getId()));
        List<Long> stepIds = list.stream().map(AutoflowStep::getId).collect(Collectors.toList());
        List<AutoflowStepForm> stepForms = autoflowStepFormDao.list(new LambdaQueryWrapper<AutoflowStepForm>().in(AutoflowStepForm::getStepId, stepIds));
        List<Long> formIds = stepForms.stream().map(AutoflowStepForm::getFormId).collect(Collectors.toList());
        List<DiyForm> forms = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(formIds)){
            forms = diyFormDao.listByIds(formIds);
        }
        return forms;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveStepConfig(StepConfigReq stepConfigVo) {
        LambdaQueryWrapper<AutoflowExtStepConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AutoflowExtStepConfig::getFlowCode, stepConfigVo.getFlowCode());
        queryWrapper.eq(AutoflowExtStepConfig::getStepNo, stepConfigVo.getStepNo());
        AutoflowExtStepConfig obj = autoflowExtStepConfigDao.getOne(queryWrapper);
        if (obj != null) {
            BeanUtil.copyProperties(stepConfigVo, obj, false);
            autoflowExtStepConfigDao.updateById(obj);
        } else {
            obj = new AutoflowExtStepConfig();
            BeanUtil.copyProperties(stepConfigVo, obj, false);
            autoflowExtStepConfigDao.save(obj);
        }
        //处理关联流程单据
        List<PrevFormReq> prevFormVoList = stepConfigVo.getPrevFlowFormArr();
        if (ObjectUtil.isNotEmpty(prevFormVoList)){
            List<AutoflowExtStepConfigPrev> addList = new ArrayList<>();
            AutoflowExtStepConfig finalObj = obj;
            List<String> prevFlowCodes = prevFormVoList.stream().map(PrevFormReq::getFlowCode).distinct().collect(Collectors.toList());
            prevFormVoList.stream().forEach(t -> {
                AutoflowExtStepConfigPrev item = new AutoflowExtStepConfigPrev();
                item.setConfigId(finalObj.getId());
                item.setPrevFlowCode(t.getFlowCode());
                item.setPrevFlowFormCode(t.getFormCode());
                addList.add(item);
            });
            //全部删除，然后新建
            autoflowExtStepConfigPrevDao.remove(new QueryWrapper<AutoflowExtStepConfigPrev>()
                    .lambda()
                    .eq(AutoflowExtStepConfigPrev::getConfigId, obj.getId())
                    .in(AutoflowExtStepConfigPrev::getPrevFlowCode, prevFlowCodes));
            autoflowExtStepConfigPrevDao.saveBatch(addList);
        }
    }

    @Override
    public List<AutoflowMain> listPrevFlow(AutoflowMainCodeReq req) {
        List<AutoflowMain> list = new ArrayList<>();
        //递归查询关联流程
        findRelFlow(list, req.getFlowCode());
        return list;
    }

    @Override
    public List<AutoflowExtSpecialFinal> listSpecialForm(AutoflowMainCodeReq req) {
        List flowList = new ArrayList<>();
        LambdaQueryWrapper<AutoflowMain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AutoflowMain::getNextFlowCode, req.getFlowCode());
        List<AutoflowMain> tmpList = autoflowMainDao.list(queryWrapper);
        flowList.add(req.getFlowCode());
        if (CollUtil.isNotEmpty(tmpList)) {
            for (AutoflowMain autoflowMain:tmpList){
                flowList.add(autoflowMain.getCode());
            }
        }
        List<AutoflowExtSpecialFinal> list = autoFlowBusinessMapper.selectListByFlow(flowList);
        list.stream().forEach(x -> {
            if (!x.getCode().equals(x.getFormModelCode())) {
                x.setCode("@@" + x.getCode());
            }else{
                x.setCode("@" + x.getCode());
            }
        });
        return  list;
    }

    @Override
    public AutoflowExtStepConfigFindVo findStepForm(AutoflowExtStepConfigReq req) {
        AutoflowExtStepConfigFindVo vo = new AutoflowExtStepConfigFindVo();
        //查询环节配置
        LambdaQueryWrapper<AutoflowExtStepConfig> configQueryWrapper = new LambdaQueryWrapper<>();
        configQueryWrapper.eq(AutoflowExtStepConfig::getFlowCode, req.getFlowCode());
        configQueryWrapper.eq(AutoflowExtStepConfig::getStepNo, req.getStepNo());
        AutoflowExtStepConfig config = autoflowExtStepConfigDao.getOne(configQueryWrapper);
        List<AutoflowExtStepConfigPrev> prevConfigList = new ArrayList<>();
        if (config != null) {
            prevConfigList = autoflowExtStepConfigPrevDao.list(new QueryWrapper<AutoflowExtStepConfigPrev>()
                    .lambda()
                    .eq(AutoflowExtStepConfigPrev::getConfigId, config.getId()));
        }
        vo.setPrevsList(prevConfigList);
        vo.setExtStepConfig(config);
        return vo;
    }

    private void findRelFlow(List<AutoflowMain> list, String flowCode) {
        if (StrUtil.isBlank(flowCode)) {
            return;
        }
        if (list == null) {
            list = new ArrayList<>();
        }
        //查询前置流程
        LambdaQueryWrapper<AutoflowMain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AutoflowMain::getNextFlowCode, flowCode);
        List<AutoflowMain> tmpList = autoflowMainDao.list(queryWrapper);
        if (CollUtil.isNotEmpty(tmpList)) {
            for (AutoflowMain tmp : tmpList) {
                list.add(tmp);
                findRelFlow(list, tmp.getCode());
            }
        }
    }
}
